package com.atguigu.tingshu.gateway.filter;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @Author GQS @Date 2024/11/2/17:25 @Description
 * 网关的全局过滤器
 */
// @Component
public class GuiguFilter implements GlobalFilter, Ordered { // 全局过滤器 定义过滤器的顺序
  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    // 获取请求 和 响应对象
    ServerHttpRequest request = exchange.getRequest();
    ServerHttpResponse response = exchange.getResponse();
    // 获取路径
    if (request.getPath().value().contains("/wxLogin")){
      // 是登陆请求直接放行
      return chain.filter(exchange);
    }
    // 从请求头中获取token
    String token = request.getHeaders().getFirst("token");
    if (StringUtils.isEmpty(token)){
      // 优化1 : 请求头中没有token 从cookie中获取
      MultiValueMap<String, HttpCookie> cookies = request.getCookies();
      if (cookies !=null){
        // 获取cookie对象
        HttpCookie httpCookie = cookies.getFirst("token");
        if (httpCookie != null){
          token = httpCookie.getValue();
          // 优化3 : 将cookie中拿到的token放进请求头中
          // request.getHeaders().set("token", token); // 这样改的是拿出来的exchange副本 不是本体
          request.mutate().header("token", token); // 正确改法
        }
      }
      // 优化2 : 将终止请求的代码放在 if (cookies !=null){} 外
      // 如果cookie中也没有token 直接拦截
      if (StringUtils.isEmpty(token)){
        response.setStatusCode(HttpStatus.UNAUTHORIZED); // 401
        // 终止请求
        return response.setComplete();
      }
    }
    // 校验通过 放行
    return chain.filter(exchange);
  }

  /**
   * 过滤器的执行顺序
   * @return null
   */
  @Override
  public int getOrder() {
    return -1;
  }
}
